home *** CD-ROM | disk | FTP | other *** search
- #include <stdio.h>
- #include <ctype.h>
-
- char *alloc(), *stralloc();
-
- #define ALLOC(type) ((type *)alloc(sizeof(type)))
-
- struct headerline {
- char *hl_line;
- struct headerline *hl_next;
- };
-
- struct header {
- struct headerline *h_header;
- struct header *h_next;
- } *headerlist, *get_header();
-
- struct headerfifo {
- struct header *f_head;
- struct header *f_tail;
- } saveheaderlist;
-
- main(argc, argv)
- int argc;
- char **argv;
- {
- int i;
- char *inputfile = NULL, *outputfile = NULL;
-
- for (argc--, argv++; argc && **argv == '-'; argc -= i, argv += i) {
- i = 1;
- while (*++*argv) {
- switch (**argv) {
- case 'h':
- if (argc <= i) {
- fprintf(stderr, "-%c: not enough args\n", **argv);
- exit(-1);
- }
- getheaders(&headerlist, argv[i++]);
- break;
- case 'o':
- if (argc <= i) {
- fprintf(stderr, "-%c: not enough args\n", **argv);
- exit(-1);
- }
- outputfile = argv[i++];
- break;
- default:
- fprintf(stderr,"Unknown switch '-%c'\n",**argv);
- exit(-1);
- }
- }
- }
-
- if (argc > 1) {
- fprintf(stderr,
- "usage: headerkludge [-a headerlist] [-h headerlist] [-o output] [input]\n");
- exit(-1);
- } else if (argc == 1)
- inputfile = *argv;
-
- parse_input(inputfile, outputfile);
- }
-
- parse_input(input, output)
- char *input, *output;
- {
- FILE *infp, *outfp;
- char buffer[BUFSIZ], *lp, *fgets();
- struct header *hp;
-
- if (input && (strcmp(input, "-") != 0)) {
- if ((infp = fopen(input, "r")) == NULL) {
- perror(input);
- exit(-1);
- }
- } else
- infp = stdin;
-
- if (output && (strcmp(output, "-") != 0)) {
- if ((outfp = fopen(output, "r")) == NULL) {
- perror(output);
- exit(-1);
- }
- } else
- outfp = stdout;
-
- lp = fgets(buffer, BUFSIZ, infp);
-
- for ( ; lp != NULL && !end_of_headers(lp); ) {
- hp = get_header(&lp, BUFSIZ, infp);
- if (want_header(headerlist, hp))
- print_header(outfp, hp);
- else
- save_header(&saveheaderlist, hp);
- }
-
- /* If there is more input, or saved headers to output,
- * indicate end_of_headers by outputting blank line
- */
- if (!feof(infp) || saveheaderlist.f_head)
- fprintf(outfp, "\n");
-
- /* Output saved headers */
- for (hp = saveheaderlist.f_head; hp != (struct header *)NULL;
- hp = hp->h_next)
- print_header(outfp, hp);
-
- /* Finish output */
- if (!feof(infp)) {
- /* Output a separator (blank line) */
- fprintf(outfp, "\n");
- while (fgets(buffer, BUFSIZ, infp))
- fprintf(outfp, "%s", buffer);
- }
-
- fclose(infp);
- fclose(outfp);
- }
-
- /* Return true if the string represents the end-of-header field
- * (for now, this is a blank line)
- */
- end_of_headers(str)
- char *str;
- {
- while (str && *str && isspace(*str)) str++;
- return (!str || !*str);
- }
-
- want_header(hl, hptr)
- struct header *hl, *hptr;
- {
- char buffer[BUFSIZ], *bp, *str;
- struct header *hp;
-
- str = hptr->h_header->hl_line;
-
- for (bp = buffer; *str && !ispunct(*str) && !isspace(*str);)
- if (isupper(*str))
- *bp++ = tolower(*str++);
- else
- *bp++ = *str++;
- *bp = '\0';
-
- for (hp = hl; hp; hp = hp->h_next)
- if (strcmp(buffer, hp->h_header->hl_line) == 0)
- return (1);
-
- return (0);
- }
-
- struct header *
- get_header(str, len, fp)
- char **str;
- int len;
- FILE *fp;
- {
- struct header *hp;
- struct headerline **hl;
-
- hp = ALLOC(struct header);
- hp->h_next = (struct header *)NULL;
- hl = &(hp->h_header);
-
- /* Read and save all header lines
- * header continuation lines begin with whitespace (but are not
- * the blank line at the end of the headers).
- * The first header line has already been read.
- */
- do {
- *hl = ALLOC(struct headerline);
- (*hl)->hl_line = stralloc(*str);
- (*hl)->hl_next = (struct headerline *)NULL;
- hl = &((*hl)->hl_next);
- *str = fgets(*str, len, fp);
- } while (*str && isspace(**str) && !end_of_headers(*str));
-
- return (hp);
- }
-
- save_header(fifo, hp)
- struct headerfifo *fifo;
- struct header *hp;
- {
- fifoappend(fifo, hp);
- }
-
- print_header(fp, hp)
- struct header *hp;
- FILE *fp;
- {
- struct headerline *hl;
-
- for (hl = hp->h_header; hl != (struct headerline *)NULL; hl = hl->hl_next)
- fprintf(fp, "%s", hl->hl_line);
- }
-
- getheaders(hl, str)
- struct header **hl;
- char *str;
- {
- char buffer[BUFSIZ], *bp;
- struct header *hp;
-
- while (str && *str) {
- for (bp = buffer; *str && !ispunct(*str) && !isspace(*str);)
- if (isupper(*str))
- *bp++ = tolower(*str++);
- else
- *bp++ = *str++;
- *bp = '\0';
- hp = ALLOC(struct header);
- hp->h_header = ALLOC(struct headerline);
- hp->h_header->hl_next = (struct headerline *)NULL;
- hp->h_header->hl_line = stralloc(buffer);
- hp->h_next = *hl;
- *hl = hp;
- /* Skip to the next header */
- while (*str && (ispunct(*str) || isspace(*str))) str++;
- }
- }
-
- char *
- stralloc(str)
- char *str;
- {
- char *sp;
-
- sp = alloc((unsigned)strlen(str)+1);
- strcpy(sp, str);
- return (sp);
- }
-
- char *
- alloc(n)
- unsigned n;
- {
- char *dp, *malloc();
-
- if ((dp = malloc(n)) == NULL) {
- fprintf(stderr, "can't malloc %d bytes\n", n);
- exit(-1);
- }
- return (dp);
- }
-
- fifoappend(fifo, hp)
- struct headerfifo *fifo;
- struct header *hp;
- {
- if (fifo->f_tail)
- fifo->f_tail->h_next = hp;
- else
- fifo->f_head = hp;
- fifo->f_tail = hp;
- }
-